/*
** gal.c: implements of gal.h
** 
** Copyright (C) 2007-2008 SKY-MOBI AS.  All rights reserved.
**
** Create date: 2007-12-27 by wandonglin
**
** This file is part of the simple gui library.
** It may not be redistributed under any circumstances.
*/

#include "sgl_i.h"
#include "gal.h"
#include "debug.h"
#include "string.h"
#include "smallfont.h"
#include "smp.h"
#include "res.h"
#include "mrc_base_i.h"

struct _screendevice scrdev;

#define MAX_CHAR_ONELINE 	48
static uint8 fontMatrix[MAX_CHAR_ONELINE + MAX_CHAR_ONELINE*32];
typedef struct
{
	uint8 *pFont;
	uint8 *pIndex;
}SGL_GB12_T;

#define MATRIX_OFFSET_SIZE (MAX_CHAR_ONELINE)

int32 SGL_DrawTextUC2Font16(uint8* pStr, int16 x, int16 y, uint16 col)
{
	char i = 0; 
	char index ;
	int offset = 0;
	SGL_GB12_T *pcText = NULL;
	SGL_GB12_T tmp = {0};
	int16 startX = x, offX, offY;
	if (!pStr)
		return MR_SUCCESS ;
	tmp.pIndex = pStr;
	tmp.pFont = pStr+MATRIX_OFFSET_SIZE;
	pcText = &tmp;
	for(i=0; pcText->pIndex[i]!=0; i++)
	{
		int w=0,h=0;
		uint16 chr;
		index = *((pcText->pIndex)+i);
		offY = y;
		for(h=0;h<16;h++)
		{
			
		      chr = (((pcText->pFont[h*2+offset])<<8)&0xFF00)|(pcText->pFont[h*2+offset+1]&0x00FF);
			offX = startX;
			for(w=0;w<16;w++)
			{
				if(chr & (1<<(16-w)))
				{
					mrc_drawPoint(offX, offY, col);
				}
				offX++;
			}
			offY++;
		}
		if (index == 8)
			startX += 8;
		else
			startX += 16;
		offset +=32;
		//index= pcText->pIndex[i];
	}
	return MR_SUCCESS;
}


uint8* SGL_GetUC2Font16(uint16*gb,uint16 len)
{
	int32 i=0,j=0;
	uint16 ch = 0;
	int32 f = mrc_open(GB16UC2_PATHNAME, MR_FILE_RDONLY);
	uint8*	pFont = fontMatrix+MATRIX_OFFSET_SIZE;
	uint8*	pIndex = fontMatrix;
	
	memset(fontMatrix,0,sizeof(fontMatrix));
	if (f)
	{
		while(i<len/2)
		{
			int ret;
			uint8*tmp = (uint8*)gb;
			ch = tmp[1]|tmp[0]<<8;
			if (ch < 255)
				pIndex[i] = 8;
			else
				pIndex[i] = 16;
			ret = mrc_seek(f,ch*32,MR_SEEK_SET);
			if (j+MATRIX_OFFSET_SIZE > sizeof(fontMatrix)-32)
				break;
			ret = mrc_read(f,pFont+j,32);
			i++;
			j += 32; 
			gb++;
		}
		mrc_close(f);
		return fontMatrix;
	}
	return NULL;

}
static int wstrlenFont(uint8 * txt,uint16 font)
{
	int lenth=0;
	uint8 * ss=(uint8*)txt;
	while((*ss<<8)+*(ss+1)!=0)
	{
		if (*ss == 0)
			lenth+=8;
		else
		{
			if (font == UTIL_FONT_12)
				lenth+=12;
			else
				lenth+=16;
		}
		ss+=2;
	}
	return lenth;
}

static uint16 GetUnicodeLenForWith(uint8 * txt,uint16 width,uint16 font)
{
	int lenth=0;
	int offset = 0;
	int step = (font == UTIL_FONT_12) ? 12 : 16;
	
	if (!txt)
		return 0;
	while(lenth<width && (*txt  || *(txt+1)))
	{
		if (*txt == 0)
		{
			lenth+=8;
		}
		else
		{
			lenth+=step;
		}
		txt +=2;
		offset +=2;
	}
	if(lenth > width)
		offset -= 2;
	return offset;
}

int32 GAL_drawTextEx(uint8* pcText, PTXTRECT pRect, uint32 color, int flag, uint16 font)
{
	uint8* pUnicode = pcText;
	PWSTR uniBuf = NULL;
	int32 result;
	
	if(!pcText)
		return MR_FAILED;
	if(font == UTIL_FONT_DEF ||font >= UTIL_FONT_MAX)
		font = UTIL_FONT_DEF;
	
	if((flag & DRAW_TEXT_EX_IS_UNICODE) == 0) {
		int32 len = strlen((char *)pcText);
		uniBuf = malloc(len*2+2);
		if(!uniBuf)
			return 0;
		str2wstr((PCSTR)pcText, uniBuf, len*2+2);
		pUnicode = (uint8 *)uniBuf;
	}
	
	if (font != UTIL_FONT_DEF)
	{
		uint8* pStr = NULL;
		uint16 offset=0;
		uint16 col = PIXEL8882PIXEL565(color);
		int32 txtLen = wstrlen((PCWSTR)pUnicode);
		int16 offsetY = pRect->startY;
		int8 h = 16;

		offset = GetUnicodeLenForWith(pUnicode, pRect->rect->w, font);
		while(txtLen > 0 && offsetY <= (pRect->rect->y + pRect->rect->h - h))
		{
			pStr = SGL_GetUC2Font16((uint16*)pUnicode, MIN(offset, txtLen));
			
			SGL_DrawTextUC2Font16(pStr, pRect->startX, offsetY, col);
			
			pUnicode += offset;
			txtLen -= offset;
			offset = GetUnicodeLenForWith(pUnicode, pRect->rect->w, font);

			offsetY += h+1;
			if(!(flag & DRAW_TEXT_EX_IS_AUTO_NEWLINE))
				break;
		}

		if(txtLen <= 0)
		{
			if((flag & DRAW_TEXT_EX_IS_UNICODE) == 0)
				result = strlen((char *)pcText);
			else
				result = wstrlen(pcText);
		}
		else {
			if((flag & DRAW_TEXT_EX_IS_UNICODE) == 0)
				result = (int32)(pcText + strlen((char *)pcText) - txtLen/2);
			else
				result = (int32)(pcText + wstrlen(pcText) - txtLen);
		}
	}
	else {
		mr_colourSt colorst;
		colorst.r = PIXEL888RED(color);
		colorst.g = PIXEL888GREEN(color);
		colorst.b = PIXEL888BLUE(color);
#if BIG_ENDIAN
		result = mrc_drawTextEx((char *)pcText, (int16)pRect->startX, (int16)pRect->startY, 
							*(pRect->rect), colorst, flag, MR_FONT_MEDIUM);
#else
		result = mrc_drawTextLeft((char *)pcText, (int16)pRect->startX, (int16)pRect->startY, 
							*(pRect->rect), colorst, (DRAW_TEXT_EX_IS_AUTO_NEWLINE & flag), MR_FONT_MEDIUM);
#endif
	}
	if(uniBuf) 
		free(uniBuf);
	return result;
}

int32 GAL_drawText(uint8* pcText, int16 x, int16 y,uint32 pixel, int isUnicode, uint16 font)
{
	uint8* pUnicode = pcText;
	PWSTR uniBuf = NULL;
	
	if(!pcText)
		return MR_FAILED;
	if(font == UTIL_FONT_DEF  ||font >= UTIL_FONT_MAX)
		font = UTIL_FONT_DEF;
	
	if(!isUnicode) {
		int32 len = strlen((char *)pcText);
		uniBuf = malloc(len*2+2);
		if(!uniBuf)
			return 0;
		str2wstr((PCSTR)pcText, uniBuf, len*2+2);
		pUnicode = (uint8 *)uniBuf;
	}
		
	if(font == UTIL_FONT_DEF)
	{
		mr_colourSt colorst;
		mr_screenRectSt rect;
		colorst.r = PIXEL888RED(pixel);
		colorst.g = PIXEL888GREEN(pixel);
		colorst.b = PIXEL888BLUE(pixel);
		rect.x = x;
		rect.y = y;
		rect.w = SCREEN_WIDTH;
		rect.h = SMP_ITEM_HEIGHT;
		//mrc_drawTextLeft((char*) pUnicode,  x,  y,  rect,  colorst, DRAW_TEXT_EX_IS_UNICODE, MR_FONT_BIG);
		mrc_drawText((char*) pUnicode,  x,  y,  colorst.r,  colorst.g,colorst.b, DRAW_TEXT_EX_IS_UNICODE, MR_FONT_MEDIUM);

	}
	else {
		uint8*pStr = NULL;
		uint16 col = PIXEL8882PIXEL565(pixel);
		pStr = SGL_GetUC2Font16((uint16*)pUnicode,wstrlen((uint8*)pUnicode));
		SGL_DrawTextUC2Font16(pStr, x, y, col);
	}
	if(uniBuf)
		free(uniBuf);
	return MR_SUCCESS;
}

int32 GAL_textWidthHeight(char* pcText, int isUnicode, uint16 font, int32* w, int32* h)
{
	uint8* pUnicode = (uint8 *)pcText;
	PWSTR uniBuf = NULL;
	int32 ret = MR_SUCCESS;
	
	*w = *h = 0;
	if(!pcText) return MR_FAILED;
	
	if(!isUnicode) {
		int32 len = strlen(pcText);
		uniBuf = (PWSTR)malloc(len*2+2);
		if(!uniBuf)
			return 0;
		str2wstr((PCSTR)pcText, uniBuf, len*2+2);
		pUnicode = (uint8 *)uniBuf;
	}

	if(font == UTIL_FONT_DEF ||font >= UTIL_FONT_MAX)
		font = UTIL_FONT_DEF;
	if (font == UTIL_FONT_12)
	{
		*w = wstrlenFont((uint8*)pUnicode,font);
		*h = 12;
	}
	else if (font == UTIL_FONT_16)
	{
		*w = wstrlenFont((uint8*)pUnicode,font);
		*h = 16;
	}
	else {
		ret = mrc_unicodeTextWidthHeight((uint16 *)pUnicode, MR_FONT_MEDIUM, w, h);
	}
	if(uniBuf)
		free(uniBuf);
	return ret;
}

int32 GAL_Initialize (VOID)
{	
	mrc_getScreenInfo(&(scrdev.scrInfo));
	return MR_SUCCESS;
}

int32 GAL_Terminate (VOID)
{
	SGL_TRACE("%s, %d: Terminate GAL\n", __FILE__, __LINE__);
	return MR_SUCCESS;
}

int32 GAL_Rectangle(GAL_GC gc, int x, int y, int w, int h, Uint32 pixel)
{
	int16 r = x + w - 1;
	int16 b = y + h - 1;
	mrc_drawLine((int16)x, (int16)y, r, (int16)y, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine((int16)x, b, r, b, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine((int16)x, (int16)y, (int16)x, b, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine(r, (int16)y, r, b, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	return MR_SUCCESS;
}

int32 GAL_Rectangle2(GAL_GC gc, int x, int y, int w, int h, int line, Uint32 pixel)
{
	int i;
	for(i = 0; i < line; i++)
		GAL_Rectangle(gc, x+i, y+i, w-2*i, h-2*i, pixel);
	return MR_SUCCESS;
}

int32 GAL_RectangleC(GAL_GC gc, int x, int y, int w, int h, gal_pixel pixel)
{
	int16 r = x + w - 1;
	int16 b = y + h - 1;
	mrc_drawLine((int16)x+1, (int16)y, r-1, (int16)y, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine((int16)x+1, b, r-1, b, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine((int16)x, (int16)y+1, (int16)x, b-1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine(r, (int16)y+1, r, b-1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	return MR_SUCCESS;
}

int32 GAL_FillFrameC(int x, int y, int w, int h, gal_pixel pixel, gal_pixel fillColor)
{
	int16 r = x + w - 1;
	int16 b = y + h - 1;
	
	mrc_drawRect(x+1, y+1, w-2, h-2, PIXEL888RED(fillColor), PIXEL888GREEN(fillColor), PIXEL888BLUE(fillColor));
	mrc_drawLine((int16)x+1, (int16)y, r-1, (int16)y, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine((int16)x+1, b, r-1, b, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine((int16)x, (int16)y+1, (int16)x, b-1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawLine(r, (int16)y+1, r, b-1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));

	mrc_drawPointEx(x+1, y+1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawPointEx(r-1, y+1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawPointEx(x+1, b-1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	mrc_drawPointEx(r-1, b-1, PIXEL888RED(pixel), PIXEL888GREEN(pixel), PIXEL888BLUE(pixel));
	return MR_SUCCESS;
}

int32 GAL_FillBox_A(int16 x, int16 y, int16 w, int16 h,int32 pixel)
{
	mrc_drawRect((int16)x, (int16)y, (int16)w, (int16)h, PIXEL888RED((pixel)), PIXEL888GREEN((pixel)), PIXEL888BLUE((pixel)));	
	return MR_SUCCESS;
}

uint16* GAL_c2u(char *cp, int32 *err, int32 *size)
{
#ifdef SDK_MOD
	return mrc_c2u(cp, err, size);
#else
	return mrc_c2uVM(cp, err, size);
	//return mrc_c2u(cp, err, size);
#endif
}


int32 GAL_DrawBackGround(int16 x, int16 y, int16 w, int16 h)
{
	/*
	int16 imgW, imgH;
	uint16* bmpData;
	int16 baseX, baseY;
	int16 dx, dy;
	int16 sx, sy;
	int16 dw, dh;

	bmpData = SGL_LoadBitmap(BMP_BGIMAGE, &imgW, &imgH);
	baseX = 0;
	baseY = SMP_TITLE_HEIGHT;
	dy = y;

	while(dy < y+h)
	{
		sy = (dy-baseY)%imgH;
		dh = (imgH-sy) < (y+h-dy) ? (imgH-sy) : (y+h-dy);
		dx = x;
		while(dx < x+w)
		{
			sx = (dx-baseX)%imgW;
			dw = (imgW-sx) < (x+w-dx) ? (imgW-sx) : (x+w-dx);

			mrc_bitmapShowEx(bmpData, dx, dy, imgW, dw, dh, BM_COPY, sx, sy);
			dx += dw;
		}
		dy += dh;
	}	
	*/
	return MR_SUCCESS;
}

/////////////////////////////////////////////////////////////
// TODO: 
char savePath[MAX_PATH_LEN];
int32 GAL_changePath(char* path)
{
	uint8 *output = NULL;
	int32 outLen = 0;
	MR_PLAT_EX_CB cb;
	int32 ret;
	
	if(!path)
		return MR_FAILED;
	ret = mrc_platEx(1204, (uint8 *)"Y", 1, (uint8 **)&output, &outLen, &cb);
	if(output && outLen)
		strcpy(savePath, (char *)output);

	ret = mrc_platEx(1204, (uint8 *)path, strlen(path), NULL, NULL, &cb);
	return ret;
}

int32 GAL_setDefaultPath(void)
{
	MR_PLAT_EX_CB cb;
	if(savePath[0] == 0)
		return MR_FAILED;
	return mrc_platEx(1204, (uint8 *)savePath, strlen(savePath), NULL, NULL, &cb);
}

uint8* GAL_readAll(const char* filename, uint32* len, int32 encrypt)
{
	uint8* content = mrc_readAll(filename, len);

	if(content != NULL && *len > 0 && encrypt)
	{}
	return content;
}

////////////////////////////////////////////////////////////

